package com.base.cn.platform.os.service.qa.question;

import com.base.cn.platform.os.common.constants.ConfigName;
import com.base.cn.platform.os.common.j2cache.CustomCacheChannel;
import com.base.cn.platform.os.common.j2cache.J2CacheRegion;
import com.base.cn.platform.os.common.j2cache.CustomCacheChannel;
import com.base.cn.platform.os.common.msg.SendMessageUtil;
import com.base.cn.platform.os.common.msg.WXTmpEnum;
import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.DateUtils;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.order.OrderStatus;
import com.base.cn.platform.os.common.utils.order.ShopType;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.dao.qa.qaattend.QaAttendDao;
import com.base.cn.platform.os.dao.qa.qareply.QaReplyDao;
import com.base.cn.platform.os.dao.qa.question.QaQuestionDao;
import com.base.cn.platform.os.entity.course.catalog.CourseCatalog;
import com.base.cn.platform.os.entity.course.cou.Course;
import com.base.cn.platform.os.entity.course.cou.buy.CourseBuyRecord;
import com.base.cn.platform.os.entity.course.cou.packageCou.PackageCourse;
import com.base.cn.platform.os.entity.manage.config.SysConfig;
import com.base.cn.platform.os.entity.qa.count.QaSumCount;
import com.base.cn.platform.os.entity.qa.qaadd.QaAdd;
import com.base.cn.platform.os.entity.qa.qaattend.QaAttend;
import com.base.cn.platform.os.entity.qa.qatag.QaTag;
import com.base.cn.platform.os.entity.qa.qatype.QaType;
import com.base.cn.platform.os.entity.qa.qatype.QaTypeCondition;
import com.base.cn.platform.os.entity.qa.question.QaQuestion;
import com.base.cn.platform.os.entity.qa.question.QuestionCondition;
import com.base.cn.platform.os.entity.qa.record.QaTeacherCommission;
import com.base.cn.platform.os.entity.qa.thumb.QaThumb;
import com.base.cn.platform.os.service.course.catalog.CourseCatalogBiz;
import com.base.cn.platform.os.service.course.cou.buy.CourseBuyRecordBiz;
import com.base.cn.platform.os.service.course.cou.packageCou.PackageCourseBiz;
import com.base.cn.platform.os.service.manage.config.SysConfigService;
import com.base.cn.platform.os.service.manage.op.affiche.OpReceiveAfficheService;
import com.base.cn.platform.os.service.manage.order.goods.OrderDetailsService;
import com.base.cn.platform.os.service.manage.order.goods.OrderService;
import com.base.cn.platform.os.service.manage.op.affiche.OpReceiveAfficheService;
import com.base.cn.platform.os.service.manage.sysUser.SysUserService;
import com.base.cn.platform.os.service.manage.teacher.SysTeacherService;
import com.base.cn.platform.os.service.manage.user.user.CusUserService;
import com.base.cn.platform.os.service.manage.user.user.SetUserDataService;
import com.base.cn.platform.os.service.qa.qaadd.QaAddBiz;
import com.base.cn.platform.os.service.qa.qaattend.QaAttendBiz;
import com.base.cn.platform.os.service.qa.qatag.QaTagBiz;
import com.base.cn.platform.os.service.qa.qatype.QaTypeBiz;
import com.base.cn.platform.os.service.qa.record.QaTeacherCommissionBiz;
import com.base.cn.platform.os.service.qa.thumb.QaThumbBiz;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author LIZHIPENG
 * @since 2018/4/12
 */
@Service
@Slf4j
public class QaQuestionBiz extends BaseBiz<QaQuestion, QaQuestionDao> {

    @Autowired
    private QaTypeBiz qaTypeBiz;
    @Autowired
    private QaAddBiz qaAddBiz;
    @Autowired
    private SysTeacherService sysTeacherService;
    @Autowired
    private QaTagBiz qaTagBiz;
    @Autowired
    private QaAttendBiz qaAttendBiz;
    @Autowired
    private QaThumbBiz qaThumbBiz;
    @Autowired
    private SetUserDataService<QaQuestion> setUserDataService;
    @Autowired
    private CourseBuyRecordBiz courseBuyRecordBiz;
    @Autowired
    private CourseCatalogBiz courseCatalogBiz;
    @Autowired
    private PackageCourseBiz packageCourseBiz;
    @Autowired
    private CusUserService cusUserService;
    @Autowired
    private QaTeacherCommissionBiz qaTeacherCommissionBiz;
    @Autowired
    private QaReplyDao qaReplyDao;
    @Autowired
    private QaAttendDao qaAttendDao;
    @Autowired
    private QaQuestionDao qaQuestionDao;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private OrderDetailsService orderDetailsService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OpReceiveAfficheService opReceiveAfficheService;
    @Autowired
    private CustomCacheChannel customCacheChannel;

    private static final String REFUND_CACHE_KEY = "qa_refund_schedule_cache_key";

    private Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();

    /**
     * 查询问题数量
     * @param condition 条件
     * @return 数量
     */
    public BigDecimal questionCount(QuestionCondition condition){
        String whereSql = getWhereSql(condition);
        return this.count(whereSql);
    }

    /**
     * 分页查询问题列表
     * @param page 分页
     * @param condition 查询条件
     * @return
     */
    public PageInfo<QaQuestion> queryQuestionListPage(Pagination page, QuestionCondition condition, BigDecimal userId, boolean qaTypeData, boolean teacherData,
                                                      boolean createUserData, boolean qaAddData, boolean attendData, boolean tagData, boolean teacherPriceData,boolean replyUser){
        if(StringUtils.isNotEmpty(condition.getContext())&&StringUtils.isEmpty(condition.getTagIds())) {
            QaTag qaTag = new QaTag();
            qaTag.setTagName(condition.getContext());
            List<QaTag> qaTypeList = qaTagBiz.queryQaTagList(qaTag);
            if(ObjectUtils.isNotEmpty(qaTypeList)){
                String collect = qaTypeList.stream().map(e -> e.getId().toString()).collect(Collectors.joining(","));
                condition.setTagIds(collect);
            }
        }
        String whereSql = this.getWhereSql(condition);
        PageInfo<QaQuestion> questionPageInfo = this.findPage(whereSql, page, null);
        List<QaQuestion> questionList = questionPageInfo.getList();
        setQuestionerAndAttender(questionList, userId);
        questionPageInfo.setList(this.setExtendData(questionList, qaTypeData, teacherData, createUserData, qaAddData, attendData, tagData, teacherPriceData));
        setReplyUserData(questionList,replyUser);
        return questionPageInfo;
    }

    /**
     * 根据ID查询问题
     * @param questionId 问题ID
     * @param qaTypeData 是否查询问答分类数据  true：是， false：否
     * @param teacherData 是否查询受问讲师数据  true：是， false：否
     * @param createUserData 是否查询提问人数据  true：是， false：否
     * @param qaAddData 是否查询追问数据  true：是， false：否
     * @return
     */
    public QaQuestion findQuestionById(BigDecimal questionId, boolean qaTypeData, boolean teacherData, boolean createUserData, boolean qaAddData, boolean attendData, boolean tagData, boolean teacherPriceData){
        QuestionCondition condition = new QuestionCondition();
        condition.setIds(questionId.toString());
        condition.setQaTypeData(qaTypeData);
        condition.setTeacherData(teacherData);
        condition.setCreateUserData(createUserData);
        condition.setQaAddData(qaAddData);
        condition.setAttendData(attendData);
        condition.setTagData(tagData);
        condition.setTeacherPriceData(teacherPriceData);
        List<QaQuestion> questionList = findQuestionByIds(condition);
        if(ObjectUtils.isNotEmpty(questionList)){
            return questionList.get(0);
        }
        return null;
    }

    /**
     * 根据ID查询问题列表，并把列表转成Map
     * @param condition 查询条件
     * @return Map<BigDecimal,QaQuestion>
     */
    public Map<BigDecimal,QaQuestion> findQuestionToMapByIds(QuestionCondition condition){
        List<QaQuestion> qaQuestionList = this.findQuestionByIds(condition);
        if(ObjectUtils.isNotEmpty(qaQuestionList)){
            return qaQuestionList.stream().collect(Collectors.toMap(e->e.getId(),e->e));
        }
        return null;
    }

    /**
     * 根据ID查询要支付的问题列表，并把列表转成Map
     * @param ids 问题ID串
     * @param qaTypeData 是否查询问答分类数据  true：是， false：否
     * @param teacherData 是否查询受问讲师数据  true：是， false：否
     * @param createUserData 是否查询提问人数据  true：是， false：否
     * @param qaAddData 是否查询追问数据  true：是， false：否
     * @return Map<BigDecimal,QaQuestion>
     */
    public Map<BigDecimal,QaQuestion> findPayQuestionMap(String ids,boolean qaTypeData, boolean teacherData, boolean createUserData, boolean qaAddData, boolean attendData, boolean tagData, boolean teacherPriceData){
        List<QaQuestion> qaQuestionList = this.find(" id in ("+ids+")",null,null);
        qaQuestionList = this.setExtendData(qaQuestionList, qaTypeData, teacherData, createUserData, qaAddData, attendData, tagData, teacherPriceData);
        if(ObjectUtils.isNotEmpty(qaQuestionList)){
            return qaQuestionList.stream().collect(Collectors.toMap(e->e.getId(),e->e));
        }
        return null;
    }

    /**
     * 根据ID查询问题
     * @param condition 查询条件
     * @return List<QaQuestion>
     */
    public List<QaQuestion> findQuestionByIds(QuestionCondition condition){
        List<QaQuestion> questionList = findQuestionList(condition,condition.isQaTypeData(),
                condition.isTeacherData(),condition.isCreateUserData(),condition.isQaAddData(),
                condition.isAttendData(),condition.isTagData(),condition.isTeacherPriceData());
        return questionList;
    }

    /**
     * 根据条件查询问题列表
     * @param condition 查询条件
     * @return
     */
    public List<QaQuestion> findQuestionList(QuestionCondition condition, boolean qaTypeData, boolean teacherData, boolean createUserData, boolean qaAddData, boolean attendData, boolean tagData, boolean teacherPriceData){
        String whereSql = this.getWhereSql(condition);
        List<QaQuestion> questionList = this.find(whereSql, condition.getCount(), null);
        return this.setExtendData(questionList, qaTypeData, teacherData, createUserData, qaAddData, attendData, tagData, teacherPriceData);
    }

    /**
     * 修改问题状态
     * @param questionIds 问题ID串
     * @param status 状态：1.正常，2.禁用，3.删除
     * @return Map<String, Object>
     */
    public Map<String, Object> updateQuestionStatus(String questionIds, int status){
            QaQuestion question = new QaQuestion();
            question.setStatus(status);

            QuestionCondition condition = new QuestionCondition();
            condition.setIds(questionIds);
            List<QaQuestion> questionList = this.findQuestionByIds(condition);
            this.updateByWhereSql(question, " id in ("+ questionIds +")");
            Map<BigDecimal,List<QaQuestion>> listMap = null;
            Map<BigDecimal,Integer> teacherQuestionListMap = new HashMap<>();
            if(ObjectUtils.isNotEmpty(questionList)){
                listMap = questionList.stream().collect(Collectors.groupingBy(e -> e.getTeacherId()));
                listMap.forEach((k,v) -> {
                    teacherQuestionListMap.put(k,v.size());
                });
            }
            if(status == 1){
                //恢复成功添加问题标签数量
                /*updateQaTagCountByQuestionIds(questionIds,status);*/
                updateNumBatch(teacherQuestionListMap,true);
                return ResultUtil.SUCCESS("恢复成功");
            }else if(status == 2){
                //禁用成功减少问题标签数量 (注:后期可能根据禁用或恢复调整问题标签数量)
                /*updateQaTagCountByQuestionIds(questionIds,status);*/
                updateNumBatch(teacherQuestionListMap,false);
                return ResultUtil.SUCCESS("禁用成功");
            }else if(status == 3){
                //删除成功减少问题标签数量
                updateQaTagCountByQuestionIds(questionIds,status);
                updateNumBatch(teacherQuestionListMap,false);
                return ResultUtil.SUCCESS("删除成功");
            }
        return ResultUtil.ERROR("系统繁忙，操作失败");
    }

    /**
     * 批量修改讲师问题数和学生数
     * @param listMap 讲师ID及问题数
     * @param isAdd 是否批量加（否为批量减）
     */
    private void updateNumBatch(Map<BigDecimal,Integer> listMap,boolean isAdd){
        if(ObjectUtils.isNotEmpty(listMap)){
            sysTeacherService.updateQuestionNumAndUserNumBatch(listMap,true,false,isAdd);
        }
    }

    /**
     * 添加或修改问题
     * @param question 问题Entity
     */
    @Transactional(rollbackFor = IllegalArgumentException.class)
    public void addOrUpdateQuestion(QaQuestion question){
        if(DataUtil.idIsNotNull(question.getId())){//修改(后台回答)
            this.updateById(question, null);
            //发送消息
            Map<String,Object> dataMap = new HashMap<>();
            Map<BigDecimal,List> dataListMap = new HashMap<>();
            dataListMap.put(question.getUserId(), Arrays.asList(question));
            dataMap.put("userIdList",Arrays.asList(question.getUserId()));
            dataMap.put("dataListMap",dataListMap);
            dataMap.put("key", WXTmpEnum.QA_REPLY);
            SendMessageUtil.sendMessage(opReceiveAfficheService,customCacheChannel,dataMap);
        }else {//添加(前台提问)
            Double questionFee = 0.0;
            //判断是否为免费问题
            if(question.getIsFree()!=1) {
                Map<String, Object> teacher =null;
                //判断TeacherId()是否存在
                if(StringUtils.isNotEmpty(question.getTeacherId())){
                    teacher = sysTeacherService.findSysTeacherById(question.getTeacherId(), false, false, false, false, false);
                }
                if(teacher!=null){
                    questionFee =   (Double)teacher.get("questionFee");
                }
                if(questionFee > 0) {
                    question.setIsFree(2);
                    question.setStatus(0);
                }else{
                    question.setIsFree(3);
                    question.setStatus(1);
                }
            }else{
                if(question.getIsFree()==1&&ObjectUtils.isNotEmpty(question.getTeacherId())){
                    question.setIsFree(3);
                }
                //如果是免费问题 设置状态为正常
                question.setStatus(1);
            }

            question.setPrice(questionFee);
            if(StringUtils.isNotEmpty(question.getTagIds())){
                question.setTagIds(","+ StringUtils.subHeadTailString(question.getTagIds(),",") +",");
            }

            //向老师提问时，判断是否增加老师的学生数与问题数
            if(DataUtil.idIsNotNull(question.getTeacherId())){
                boolean userNum = false;
                QuestionCondition condition = new QuestionCondition();
                condition.setUserId(question.getUserId());
                condition.setTeacherId(question.getTeacherId());
                BigDecimal count = this.count("userId=" + question.getUserId() + " and teacherId=" + question.getTeacherId());
                if(!DataUtil.idIsNotNull(count)){
                    userNum = true;
                }
                if(question.getStatus() !=null && question.getStatus().intValue()==1){
                    sysTeacherService.updateQuestionNumAndUserNum(question.getTeacherId(), true, userNum);
                }
            }

            this.save(question);
            //修改用户的提问数
            cusUserService.updateUserNumberOfStatistics(question.getUserId(),"qaNum",1);

            //更新问答分类的数量
            QaType qaType = qaTypeBiz.findQaTypeById(question.getTypeId());
            QaType _qaType = new QaType();
            _qaType.setId(question.getTypeId());
            _qaType.setQuestionNum(qaType.getQuestionNum() +1);
            qaTypeBiz.updateById(_qaType, null);

            //更新问题标签的数量
            if(StringUtils.isNotEmpty(question.getTagIds())){
                updateQaTagCount(question.getTagIds(),1);
            }
        }
    }

    /**
     * 更新问题标签数
     *
     * @param tagIds
     */
    private void updateQaTagCount(String tagIds,int value) {
        String _tagIds = StringUtils.subHeadTailString(tagIds, ",");
        QaTag tag = new QaTag();
        tag.setIds(_tagIds);
        List<QaTag> tagList = qaTagBiz.queryQaTagList(tag);
        if (ObjectUtils.isNotEmpty(tagList)) {
            List<QaTag> _tagList = new ArrayList<>();
            for (QaTag qaTag : tagList) {
                QaTag _tag = new QaTag();
                _tag.setId(qaTag.getId());
                _tag.setQuestionNum(qaTag.getQuestionNum() + value);
                _tagList.add(_tag);
            }
            qaTagBiz.updateBatch(_tagList);
        }
    }

    /**
     * 根据问题Id更新问题标签数
     *
     * @param questionIds
     */
    private void updateQaTagCountByQuestionIds(String questionIds,int status){
        List<QaQuestion> questionList = this.find(" id in("+questionIds+")", null,null);
        StringBuffer tagIds = new StringBuffer();
        questionList.stream().forEach(v -> {
            tagIds.append(StringUtils.subHeadTailString(v.getTagIds(),",")).append(",");
        });
        if (status == 1){
            updateQaTagCount(tagIds.toString(),1);
        }
        if (status == 2 || status == 3){
            updateQaTagCount(tagIds.toString(),-1);
        }
    }

    /**
     * 前台查看问题详情方法
     * @param questionId 问题ID
     * @param userId 当前登录用户ID
     * @param userData 是否设置提问用户信息
     * @param teacherData 是否设置讲师信息
     * @param addData 是否设置追问信息
     * @param attendData 是否设置旁听用户信息
     * @param tagData 是否设置标签信息
     * @return
     */
    public QaQuestion findQuestionByIdForFront(BigDecimal questionId, BigDecimal userId, boolean qaTypeData, boolean userData, boolean teacherData,boolean addData, boolean attendData, boolean tagData, boolean teacherPriceData){
        QaQuestion question = this.findQuestionById(questionId, qaTypeData, teacherData, userData, addData, attendData, tagData, teacherPriceData);
        if(ObjectUtils.isNotEmpty(question)){
            //后台回答者信息(针对免费提问问题回答后显示回答者信息)
            if (DataUtil.idIsNotNull(question.getReplyUserId())){
                Map<String, Object> replyUser = sysUserService.findSysUserById(question.getReplyUserId(), false, false, false);
                question.setReplyUser(replyUser);
            }
            //问题浏览量+1
            QaQuestion qaQuestion = new QaQuestion();
            qaQuestion.setId(questionId);
            qaQuestion.setBrowseNum(question.getBrowseNum() +1);
            this.addOrUpdateQuestion(qaQuestion);
            setQuestionerAndAttender(question, userId);
            setThumber(question, userId);
            return question;
        }
        return null;
    }

    /**
     * 查询我的问答列表
     * @param page 分页
     * @param userId 用户ID
     * @param queryType 查询类型：1.我提问的-免费，2.我回答(评论)的，3.我提问的-付费，4.我围观的
     * @param qaTypeData 是否设置问答类型（true：是，false：否）
     * @param userData 是否设置提问用户信息（true：是，false：否）
     * @param teacherData 是否设置讲师信息（true：是，false：否）
     * @param addData 是否设置追问信息（true：是，false：否）
     * @param attendData 是否设置旁听用户信息（true：是，false：否）
     * @param tagData 是否设置标签信息（true：是，false：否）
     * @return
     */
    public PageInfo<QaQuestion> queryMyQuestionList(Pagination page, BigDecimal userId, int queryType, boolean qaTypeData, boolean userData, boolean teacherData, boolean addData, boolean attendData, boolean tagData, boolean teacherPriceData){
        PageInfo<QaQuestion> questionPageinfo = new PageInfo<>();
        if(queryType == 1){
            QuestionCondition condition = new QuestionCondition();
            condition.setUserId(userId);
            condition.setNotNoFree(true);
            questionPageinfo = queryQuestionListPage(page, condition, userId, qaTypeData, teacherData, userData, addData, attendData, tagData, teacherPriceData,false);
        }else if(queryType == 2){
            PageHelper.startPage(page.getCurrentPage(), page.getPageSize());
            Page<QaQuestion> questionPage = qaReplyDao.getMyReplyQuestionList(QaQuestion.class, userId);
            questionPageinfo = new PageInfo<>(questionPage);
            setQuestionerAndAttender(questionPageinfo.getList(), userId);
        }else if(queryType == 3){
            QuestionCondition condition = new QuestionCondition();
            condition.setUserId(userId);
            condition.setIsFree(2);
            questionPageinfo = queryQuestionListPage(page, condition, userId, qaTypeData, teacherData, userData, addData, attendData, tagData, teacherPriceData,false);
        }else if(queryType == 4){
            PageHelper.startPage(page.getCurrentPage(), page.getPageSize());
            Page<QaQuestion> questionPage = qaAttendDao.getMyAttendQuestionList(QaQuestion.class, userId);
            questionPageinfo = new PageInfo<>(questionPage);
            setQuestionerAndAttender(questionPageinfo.getList(), userId);
        }
        questionPageinfo.setList(this.setExtendData(questionPageinfo.getList(), qaTypeData, teacherData, userData, addData, attendData, tagData, teacherPriceData));
        return questionPageinfo;
    }

    /**
     * 校验用户是否可以免费提问
     * @param userId 用户ID
     * @return
     */
    public Map<String, Object> checkUserIsQuestion(BigDecimal userId){
        CourseBuyRecord courseBuyRecord = new CourseBuyRecord();
        courseBuyRecord.setUserId(userId);
        courseBuyRecord.setValidTime(new Date());
        Pagination page = new Pagination();
        page.setCurrentPage(1);
        page.setPageSize(10);
        PageInfo<CourseBuyRecord> courseBuyRecordPageInfo = courseBuyRecordBiz.findCourseBuyRecordPage(courseBuyRecord,page,false, false, false,false, false, false,false);
        List<CourseBuyRecord> list = courseBuyRecordPageInfo.getList();
        if(ObjectUtils.isNotEmpty(list)){
            return ResultUtil.SUCCESS();
        }
        return ResultUtil.ERROR("您必须购买课程或套餐后才能免费提问题");
    }

    /**
     * 根据套餐ID查询课程列表
     * @param packageId
     * @return
     */
    public List<Course> getCourseListByPackageId(BigDecimal packageId){
        List<PackageCourse> packageCourseList = packageCourseBiz.findPackageCourseByPackageId(packageId, true);
        List<Course> courseList = new ArrayList<>();
        if(ObjectUtils.isNotEmpty(packageCourseList)){
            for (PackageCourse packageCourse : packageCourseList) {
                courseList.add(packageCourse.getCourse());
            }
        }
        return courseList;
    }

    /**
     * 根据课程ID查询章节列表
     * @param courseId 课程ID
     * @return
     */
    public List<CourseCatalog> getCourseCatalogByCourseId(BigDecimal courseId){
        List<CourseCatalog> catalogList = courseCatalogBiz.findCourseCatalogLayeredByCourseId(courseId,BigDecimal.ZERO,courseId, false, false, false, false,false);
        return catalogList;
    }

    //========================================

    /**
     * 拼接sql语句
     * @param condition 拼接条件
     * @return
     */
    private String getWhereSql(QuestionCondition condition){
        StringBuilder whereSql = new StringBuilder(" 1=1");
        if(!condition.isNoStatusLimit()){
            whereSql.append(" and status != 3 and status !=0");
        }
        if(ObjectUtils.isNotEmpty(condition)){
            if(DataUtil.idIsNotNull(condition.getId())){
                whereSql.append(" and id").append("=").append(condition.getId());
            }
            if(StringUtils.isNotEmpty(condition.getIds())){
                whereSql.append(" and id in (").append(StringUtils.subHeadTailString(condition.getIds(), ",")).append(")");
            }
            if(StringUtils.isNotEmpty(condition.getContext())){
                whereSql.append(" and context like '%").append(condition.getContext()).append("%'");
            }
            if(DataUtil.idIsNotNull(condition.getUserId())){
                whereSql.append(" and userId=").append(condition.getUserId());
            }
            if(DataUtil.idIsNotNull(condition.getTeacherId())){
                whereSql.append(" and teacherId = ").append(condition.getTeacherId());
            }
            if(ObjectUtils.isNotEmpty(condition.getIsFree())){
                whereSql.append(" and isFree=").append(condition.getIsFree());
            }
            if(ObjectUtils.isNotEmpty(condition.getCompleteStatus())){
                whereSql.append(" and completeStatus = ").append(condition.getCompleteStatus());
            }
            if(DataUtil.idIsNotNull(condition.getTypeId())){
                whereSql.append(" and typeId = ").append(condition.getTypeId());
            }
            if(StringUtils.isNotEmpty(condition.getQaTypeIds())){
                whereSql.append(" and typeId in (").append(StringUtils.subHeadTailString(condition.getQaTypeIds(),",")).append(")");
            }
            if(condition.isNotNoFree()){
                whereSql.append(" and isFree in (1,3)");
            }
            if(StringUtils.isNotEmpty(condition.getTagIds())){
                if(ObjectUtils.isNotEmpty(condition.getSelectFrom()) && condition.getSelectFrom()==2 && StringUtils.isNotEmpty(condition.getContext())){
                    String[] split = condition.getTagIds().split(",");
                    for(String id :split){
                        whereSql.append(" or tagIds like concat('%','").append(id).append("','%')");
                    }
                }else {
                    whereSql.append(" and tagIds like '%,").append(StringUtils.subHeadTailString(condition.getTagIds(), ",") ).append(",%'");
                }
            }
            if(ObjectUtils.isNotEmpty(condition.getStatus())){
                whereSql.append(" and status = ").append(condition.getStatus());
            }
            if(StringUtils.isNotEmpty(condition.getReplyStartTime())){
                whereSql.append(" and replyTime >='").append(condition.getReplyStartTime()).append("'");
            }
            if(StringUtils.isNotEmpty(condition.getReplyEndTime())){
                whereSql.append(" and replyTime <='").append(condition.getReplyEndTime()).append("'");
            }
            if(condition.isNowQa()){
                Date nowTime = new Date();
                whereSql.append(" and createTime >= '").append(DateUtils.format(nowTime,"yyyy-MM-dd")).append(" 00:00:00'");
                whereSql.append(" and createTime <='").append(DateUtils.format(nowTime,"yyyy-MM-dd")).append(" 23:59:59'");
            }
            if (StringUtils.isNotEmpty(condition.getIsAllowedRefund())){
                whereSql.append(" and isAllowedRefund =").append(condition.getIsAllowedRefund());
            }
            //查询来源于前台
            if(ObjectUtils.isNotEmpty(condition.getSelectFrom()) && condition.getSelectFrom()==2){
                whereSql.append(" and (privacy=1");
                if(DataUtil.idIsNotNull(condition.getUserId())){
                    whereSql.append(" or (userId=").append(condition.getUserId()).append("and privacy=2)");
                }
                whereSql.append(")");
            }
        }
        whereSql.append(" order by id desc");
        return whereSql.toString();
    }

    /**
     * 设置扩展数据
     * @param questionList 问题列表
     * @param qaTypeData 是否设置问答分类数据  true：是，false：否
     * @param teacherData 是否设置受问讲师数据  true：是，false：否
     * @param createUserData 是否设置创建人数据  true：是，false：否
     * @param qaAddData 是否设置追问数据  true：是，false：否
     * @param attendData 是否设置问答旁听用户  true：是，false：否
     * @param tagData 是否设置问答标签数据 true：是，false：否
     * @param teacherPriceData 是否设置讲师收益信息 true：是，false：否
     * @return
     */
    private List<QaQuestion> setExtendData(List<QaQuestion> questionList, boolean qaTypeData, boolean teacherData, boolean createUserData,
                                           boolean qaAddData, boolean attendData, boolean tagData, boolean teacherPriceData){
        if(ObjectUtils.isNotEmpty(questionList)){
            if(qaTypeData){
                questionList = setQaTypeData(questionList, qaTypeData);
            }
            if(teacherData){
                questionList = setTeacherData(questionList, teacherData);
            }
            if(createUserData){
                questionList = setCreateUserData(questionList, createUserData);
            }
            if(qaAddData){
                questionList = setQaAddData(questionList, qaAddData);
            }
            if(attendData){
                questionList = setQaAttendData(questionList, attendData);
            }
            if(tagData){
                questionList = setQaTagData(questionList, tagData);
            }
            if(teacherPriceData){
                questionList = setTeacherPriceData(questionList, teacherPriceData);
            }
        }
        return questionList;
    }

    /**
     * 设置问答分类数据
     * @param questionList 问题列表
     * @param qaTypeData 是否设置问答分类数据（true：是，false：否）
     * @return
     */
    private List<QaQuestion> setQaTypeData(List<QaQuestion> questionList, boolean qaTypeData){
        if(ObjectUtils.isNotEmpty(questionList) && qaTypeData){
            String qaTypeIds = questionList.stream().map(e -> e.getTypeId().toString()).distinct().collect(Collectors.joining(","));
            if(StringUtils.isNotEmpty(qaTypeIds)){
                QaTypeCondition qaTypeCondition = new QaTypeCondition();
                qaTypeCondition.setIds(qaTypeIds);
                List<QaType> qaTypeList = qaTypeBiz.findQaTypeList(qaTypeCondition);
                if(ObjectUtils.isNotEmpty(qaTypeList)){
                    for (QaQuestion question : questionList) {
                        for (QaType qaType : qaTypeList) {
                            if(question.getTypeId().equals(qaType.getId())){
                                question.setQaType(qaType);
                                break;
                            }
                        }
                    }
                }
            }
        }
        return questionList;
    }

    /**
     * 设置受问讲师数据
     * @param questionList 问题列表
     * @param teacherData 是否设置受问讲师数据（true：是，false：否）
     * @return
     */
    private List<QaQuestion> setTeacherData(List<QaQuestion> questionList, boolean teacherData){
        if(ObjectUtils.isNotEmpty(questionList) && teacherData){
            String teacherIds = questionList.stream().map(e -> e.getTeacherId().toString()).distinct().collect(Collectors.joining(","));
            if(StringUtils.isNotEmpty(teacherIds)){
                Map<BigDecimal, Map<String, Object>> teacherMaps = sysTeacherService.findSysTeacherToMapByIds(teacherIds, false, false, false, false, false);
                if(ObjectUtils.isNotEmpty(teacherMaps)){
                    for (QaQuestion question : questionList) {
                        Map<String, Object> teahcerMap = teacherMaps.get(question.getTeacherId());
                        question.setTeacherMap(teahcerMap);
                    }
                }
            }
        }
        return questionList;
    }

    /**
     * 设置提问用户数据
     * @param questionList 问题列表
     * @param createUserData 是否设置提问人数据（true：是，false：否）
     * @return
     */
    private List<QaQuestion> setCreateUserData(List<QaQuestion> questionList, boolean createUserData){
        if(ObjectUtils.isNotEmpty(questionList) && createUserData){
            questionList = setUserDataService.setUserData(questionList, createUserData);
        }
        return questionList;
    }

    /**
     * 设置追问数据
     * @param questionList 问题列表
     * @param qaAddData 是否设置追问数据（true：是，false：否）
     * @return
     */
    private List<QaQuestion> setQaAddData(List<QaQuestion> questionList, boolean qaAddData){
        if(ObjectUtils.isNotEmpty(questionList) && qaAddData){
            String questionIds = questionList.stream().map(e -> e.getId().toString()).collect(Collectors.joining(","));
            QaAdd qaAdd = new QaAdd();
            qaAdd.setQuestionIds(questionIds);
            List<QaAdd> qaAddList = qaAddBiz.findQaAddList(qaAdd);
            if(ObjectUtils.isNotEmpty(qaAddList)){
                Map<BigDecimal, List<QaAdd>> qaAddMap = qaAddList.stream().collect(Collectors.groupingBy(QaAdd::getQuestionId));
                for (QaQuestion question : questionList) {
                    question.setQaAddList(qaAddMap.get(question.getId()));
                }
            }
        }
        return questionList;
    }

    /**
     * 设置问答旁听用户
     * @param questionList 问题列表
     * @param attendData 是否设置问答旁听用户（true：是，false：否）
     * @return
     */
    private List<QaQuestion> setQaAttendData(List<QaQuestion> questionList, boolean attendData){
        if(ObjectUtils.isNotEmpty(questionList) && attendData){
            String questionIds = questionList.stream().map(e -> e.getId().toString()).collect(Collectors.joining(","));
            QaAttend qaAttend = new QaAttend();
            qaAttend.setQuestionIds(questionIds);
            qaAttend.setCount(18);
            List<QaAttend> qaAttendList = qaAttendBiz.findQaAttendList(qaAttend, attendData);
            if(ObjectUtils.isNotEmpty(qaAttendList)){
                Map<BigDecimal, List<QaAttend>> attendMap = qaAttendList.stream().collect(Collectors.groupingBy(e -> e.getQuestionId()));
                for (QaQuestion qaQuestion : questionList) {
                    qaQuestion.setAttendList(attendMap.get(qaQuestion.getId()));
                }
            }
        }
        return questionList;
    }

    /**
     * 设置问答标签数据
     * @param questionList 问题列表
     * @param tagData 是否设置标签数据（true：是，false：否）
     * @return
     */
    private List<QaQuestion> setQaTagData(List<QaQuestion> questionList, boolean tagData){
        if(ObjectUtils.isNotEmpty(questionList) && tagData){
            String tagIds = DataUtil.joining(questionList, QaQuestion::getTagIds);
            tagIds = DataUtil.filterNotNumberStr(tagIds);
            QaTag qaTag = new QaTag();
            qaTag.setIds(tagIds);
            List<QaTag> qaTagList = qaTagBiz.queryQaTagList(qaTag);
            if(ObjectUtils.isNotEmpty(qaTagList)){
                Map<BigDecimal, QaTag> tagMap = qaTagList.stream().collect(Collectors.toMap(QaTag::getId, e -> e));
                for (QaQuestion qaQuestion : questionList) {
                    if(qaQuestion.getTagIds() != null && StringUtils.isNotEmpty(qaQuestion.getTagIds())){
                        String[] strArr = StringUtils.subHeadTailString(qaQuestion.getTagIds(), ",").split(",");
                        List<QaTag> _tagList = new ArrayList<>();
                        for (String s : strArr) {
                            QaTag tag = tagMap.get(new BigDecimal(s));
                            _tagList.add(tag);
                        }
                        qaQuestion.setTagList(_tagList);
                    }
                }
            }
        }
        return questionList;
    }

    /**
     * 给问题列表设置回答者
     * @param questionList 问题列表
     * @param replyUser 是否设置回答者
     * @return List<QaQuestion>
     */
    private void setReplyUserData(List<QaQuestion> questionList, boolean replyUser){
        if(ObjectUtils.isNotEmpty(questionList) && replyUser){
            String replyUserIds = questionList.stream().filter(e->ObjectUtils.isNotEmpty(e.getReplyUserId())).map(e -> e.getReplyUserId().toString()).collect(Collectors.joining(","));
            Map<BigDecimal, Map<String, Object>> sysUserMapByUserIds = sysUserService.findSysUserMapByUserIds(replyUserIds, false, false, false);
            if(ObjectUtils.isNotEmpty(sysUserMapByUserIds)){
                for (QaQuestion question : questionList) {
                    question.setReplyUser(sysUserMapByUserIds.get(question.getReplyUserId()));
                }
            }
        }
    }

    /**
     * 设置查看问题的用户是否为提问者、围观者
     * @param qaQuestion 问题
     * @param userId 用户ID
     */
    private void setQuestionerAndAttender(QaQuestion qaQuestion, BigDecimal userId){
        if(ObjectUtils.isNotEmpty(qaQuestion)){
            List<QaQuestion> qaQuestionList = new ArrayList<>();
            qaQuestionList.add(qaQuestion);
            setQuestionerAndAttender(qaQuestionList, userId);
        }
    }

    /**
     * 设置查看问题的用户是否为提问者、围观者
     * @param questionList 问题列表
     * @param userId 用户ID
     */
    private void setQuestionerAndAttender(List<QaQuestion> questionList, BigDecimal userId){
        if(ObjectUtils.isNotEmpty(questionList)){
            if(DataUtil.idIsNotNull(userId)){
                String questionIds = questionList.stream().map(e -> e.getId().toString()).distinct().collect(Collectors.joining(","));
                QaAttend qaAttend = new QaAttend();
                qaAttend.setQuestionIds(questionIds);
                qaAttend.setUserId(userId);
                List<QaAttend> qaAttendList = qaAttendBiz.findQaAttendList(qaAttend, false);
                Map<BigDecimal, List<QaAttend>> map = new HashMap<>();
                if(ObjectUtils.isNotEmpty(qaAttendList)){
                    map = qaAttendList.stream().collect(Collectors.groupingBy(QaAttend::getQuestionId));
                }
                for (QaQuestion qaQuestion : questionList) {
                    List<QaAttend> attends = map.get(qaQuestion.getId());

                    if(ObjectUtils.isNotEmpty(attends)){
                        qaQuestion.setAttender(true);
                    }else {
                        qaQuestion.setAttender(false);
                    }

                    if(qaQuestion.getUserId().equals(userId)){
                        qaQuestion.setQuestioner(true);
                    }else {
                        qaQuestion.setQuestioner(false);
                    }
                }
            }else {
                for (QaQuestion qaQuestion : questionList) {
                    qaQuestion.setQuestioner(false);
                    qaQuestion.setAttender(false);
                }
            }
        }
    }

    /**
     * 设置问题的点赞者
     * @param question 问题
     * @param userId 用户ID
     */
    private void setThumber(QaQuestion question, BigDecimal userId){
        if(ObjectUtils.isNotEmpty(question)){
            List<QaQuestion> list = new ArrayList<>();
            list.add(question);
            setThumber(list, userId);
        }
    }

    /**
     * 设置问题的点赞者
     * @param questionList 问题列表
     * @param userId 用户ID
     */
    private void setThumber(List<QaQuestion> questionList, BigDecimal userId){
        if(ObjectUtils.isNotEmpty(questionList)){
            if(DataUtil.idIsNotNull(userId)){
                String questionIds = questionList.stream().map(e -> e.getId().toString()).collect(Collectors.joining(","));
                QaThumb qaThumb = new QaThumb();
                qaThumb.setQuestionIds(questionIds);
                qaThumb.setUserId(userId);
                List<QaThumb> qaThumbs = qaThumbBiz.queryQaThumbList(qaThumb);
                if(ObjectUtils.isNotEmpty(qaThumbs)){
                    Map<BigDecimal, List<QaThumb>> map = qaThumbs.stream().collect(Collectors.groupingBy(QaThumb::getQuestionId));
                    questionList.forEach(e->e.setThumber(ObjectUtils.isNotEmpty(map.get(e.getId()))));
                    return;
                }
            }
            questionList.forEach(e->e.setThumber(false));
        }
    }
    /**
     * 给问题列表设置讲师分成信息
     * @param questionList 问题列表
     * @param teacherPriceData 是否设置讲师分成信息
     * @return List<QaQuestion>
     */
    private List<QaQuestion> setTeacherPriceData(List<QaQuestion> questionList, boolean teacherPriceData){
        if(ObjectUtils.isNotEmpty(questionList) && teacherPriceData){
            String questionIds = questionList.stream().map(e -> e.getId().toString()).collect(Collectors.joining(","));
            QaTeacherCommission qaTeacherCommission = new QaTeacherCommission();
            qaTeacherCommission.setQuestionIds(questionIds);
            List<QaTeacherCommission> qaTeacherCommissionList = qaTeacherCommissionBiz.queryQaTeacherCommissionList(qaTeacherCommission, false, false, false);
            if(ObjectUtils.isNotEmpty(qaTeacherCommissionList)){
                for (QaQuestion qaQuestion : questionList) {
                    for (QaTeacherCommission teacherCommission : qaTeacherCommissionList) {
                        if(qaQuestion.getId().equals(teacherCommission.getQuestionId())){
                            qaQuestion.setQaTeacherCommission(teacherCommission);
                            break;
                        }
                    }
                }
            }
        }
        return questionList;
    }

    /**
     * 查询问答总数量数据
     * @return QaSumCount
     */
    public QaSumCount queryQaSumCount(){
        QaSumCount qaSumCount = qaQuestionDao.queryQaSumCount(QaQuestion.class);
        if(qaSumCount==null){
            qaSumCount = new QaSumCount();
        }
        return qaSumCount;
    }

    /**
     * 问答退费
     */
    @Async
    public void qaRefund() {
        //查询系统退费时间
        TreeMap<String, String>  configMap = sysConfigService.getSysConfigContext(ConfigName.QAREFUND);
        int refundTime = Integer.parseInt(configMap.get("refundTime"));
        String refundSwitch = configMap.get("refundSwitch");
        if(refundSwitch.equals("ON")){
            //查询所有可退费的问答
            QaQuestion qaQuestion = this.findOne(" (unix_timestamp() - unix_timestamp(createTime)) >=("+refundTime+"*24*60*60) and status =1 and completeStatus=1 and isFree =2 and isAllowedRefund=1",null);
            //通过问答的id和提问者的id获取到订单流水中数据
            if (ObjectUtils.isNotEmpty(qaQuestion)){
                Map<String, Object> condition = new HashMap<>();
                condition.put("shopId",qaQuestion.getId());
                condition.put("userId",qaQuestion.getUserId());
                condition.put("shopType", ShopType.ORDER_SHOP_QA);
                //获取订单流水列表
                List<Map<String, Object>> orderDetailsList = orderDetailsService.findOrderDetailsList(condition);
                if(ObjectUtils.isNotEmpty(orderDetailsList)){
                    Map<String, Object> orderDetails = orderDetailsList.get(0);
                    //获取订单id
                    String id = orderDetails.get("orderId").toString();
                    BigDecimal orderId = new BigDecimal(id);
                    orderService.updateOrderStatus(BigDecimal.ZERO, orderId, OrderStatus.REFUND, null, null, null, null, null, null);
                    //更新退费问题的状态
                    qaQuestion.setCompleteStatus(3);
                    this.updateById(qaQuestion,null);
                }
            }
            //方法执行完毕删除缓存(防止重复退费)
            customCacheChannel.evict(J2CacheRegion.ONE_MINUTE_REGION.getKey(),REFUND_CACHE_KEY);
        }
    }

}
